using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace cs2335.CCT
{
    class TreeView : ITreeView, IComponent
    {
        protected string text, name;
        protected Rectangle mainRectangle;
        protected Rectangle scrollRectangle, upbutton, downbutton, positionbar;
        protected SolidBrush mainBrush;
        protected SolidBrush scrollBrush = new SolidBrush(Color.LightGray);
        protected SolidBrush triangleBrush = new SolidBrush(Color.Gold);
        protected SolidBrush updownBrush = new SolidBrush(Color.Blue);
        protected SolidBrush positionBrush = new SolidBrush(Color.LightSteelBlue);
        protected SolidBrush selectedBrush = new SolidBrush(Color.Gold);
        protected Font font;
        protected CCTForm owner;
        protected bool hasFocus, hidden, scroll;
        protected ITreeNodeCollection nodes;
        protected ITreeNode selected;
        protected int domain;
        protected StringFormat labelFormat = new StringFormat(StringFormatFlags.NoClip);
        protected StringFormat buttonFormat = new StringFormat(StringFormatFlags.NoClip);
        protected int mouseX;
        protected int mouseY, count;
        protected Rectangle select;
        protected string selecttext;

        public TreeView()
        {
            name = "TreeView";
            mainRectangle = new Rectangle(300, 0, 150, 200);
            mainBrush = new SolidBrush(Color.White);
            font = new Font("SansSerif", 8);
            hasFocus = false;
            hidden = false;
            scroll = false;
            nodes = new TreeNodeCollection();
            Scrollable = false;
        }
      
        #region IComponent Members

        #region Properties

        public Point Location
        {
            get { return mainRectangle.Location; }
            set { mainRectangle.Location = value; Invalidate(); }
        }

        public Rectangle Bounds
        {
            get { return mainRectangle; }
            set { mainRectangle = value; Invalidate(); }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public System.Drawing.Font Font
        {
            get { return font; }
            set { font = value; Invalidate(); }
        }

        public string Text
        {
            get { return text; }
            set { text = value; Invalidate(); }
        }

        public CCTForm Owner
        {
            get { return owner; }
            set { owner = value; }
        }

        public Color BackColor
        {
            get { return mainBrush.Color; }
            set { mainBrush.Color = value; Invalidate(); }
        }
        #endregion

        #region Events

        public event EventHandler Click;

        public event EventHandler GotFocus;

        public event EventHandler LostFocus;

        public event EventHandler KeyPress;

        public event EventHandler KeyDown;

        public event EventHandler Paint;

        #endregion

        public void Invalidate()
        {
            if (owner != null)
            {
                owner.Invalidate();
            }
        }

        public void Hide()
        {
            hidden = true;
            Invalidate();
        }

        public void Show()
        {
            hidden = false;
            Invalidate();
        }

       
        public void PaintNode(Graphics g, List<ITreeNode> nodes, int x, int y)
        {
            
            domain = mainRectangle.Height / 12;
            foreach (ITreeNode i in nodes)
            {
                int tempw = mainRectangle.Right - (x + 10);
                count++;
                    if (Scrollable || count > domain)
                    {
                        scrollRectangle = new Rectangle(mainRectangle.Right - 15, mainRectangle.Top, 15, mainRectangle.Height);
                        upbutton = new Rectangle(mainRectangle.Right - 15, mainRectangle.Top, 15, 15);
                        downbutton = new Rectangle(mainRectangle.Right - 15, mainRectangle.Bottom - 15, 15, 15);
                        //int pbar = mainRectangle.Top + 15 + (top * ((scrollRectangle.Height - 40) / (list.Count - domain)));
                        positionbar = new Rectangle(mainRectangle.Right - 15, mainRectangle.Right, 15, 10);
                        //change width of Item rectangles so it does not conflict with scrollbar
                        tempw += - 15;

                        //draw rectangles
                        g.FillRectangle(scrollBrush, scrollRectangle);
                        g.FillRectangle(updownBrush, upbutton);
                        g.FillRectangle(updownBrush, downbutton);
                        g.FillRectangle(positionBrush, positionbar);

                        // Triangles (point arrays) for up and down buttons
                        Point[] uptriangle = {new Point(upbutton.X+2,upbutton.Y+11),new Point(upbutton.X+8,upbutton.Y+5),
                        new Point(upbutton.X+13,upbutton.Y+11)};
                        Point[] downtriangle = {new Point(downbutton.X+2,downbutton.Y+5),new Point(downbutton.X+8,downbutton.Y+11),
                        new Point(downbutton.X+13,downbutton.Y+5)};

                        //draw triangles
                        g.FillPolygon(triangleBrush, uptriangle);
                        g.DrawPolygon(Pens.Black, uptriangle);
                        g.FillPolygon(triangleBrush, downtriangle);
                        g.DrawPolygon(Pens.Black, downtriangle);

                        //draw borders
                        g.DrawRectangle(Pens.Black, positionbar);
                        g.DrawRectangle(Pens.Black, upbutton);
                        g.DrawRectangle(Pens.Black, downbutton);
                        g.DrawRectangle(Pens.Black, scrollRectangle);
                        //g.DrawLine(Pens.Black, positionbar.X + 3, positionbar.Y + 4, positionbar.X + 12, positionbar.Y + 4);
                        //g.DrawLine(Pens.Black, positionbar.X + 3, positionbar.Y + 6, positionbar.X + 12, positionbar.Y + 6);
                    }
                Rectangle temp = new Rectangle(x + 10, y,tempw , 12);
              
                Rectangle button = new Rectangle(x+1, y+3,8, 8);
                g.FillRectangle(Brushes.White, temp);
                g.DrawRectangle(Pens.Black, button);
                

                if (button.Contains(mouseX, mouseY))
                {
                    i.Expanded = !i.Expanded;
                    selected = i;
                }
                
                if (temp.Contains(mouseX, mouseY))
                    selected = i;

                if (i == selected)
                {
                    select = temp;
                    selecttext = i.Text;
                }
                if (i.Expanded)
                    g.DrawString("-", font, Brushes.Black, button.X - 1, button.Y - 3);
                else
                    g.DrawString("+", font, Brushes.Black, button.X-1, button.Y-3);

                g.DrawString(i.Text, font, Brushes.Black, temp, labelFormat);

                if (i.Nodes.List.Count != 0 && i.Expanded)
                {
                    y += 12;
                    PaintNode(g, i.Nodes.List, x + 12, y);
                }

       
                y += 12;
            }
            g.DrawRectangle(Pens.Black, mainRectangle);

            g.FillRectangle(Brushes.Gold, select);
            g.DrawString(selecttext, font, Brushes.Black, select, labelFormat);

        }

        
        public void OnPaint(PaintEventArgs e)
        {

            if (!hidden)
            {
                count = 0;
                Graphics g = e.Graphics;
                g.FillRectangle(mainBrush, mainRectangle);
                PaintNode(g, nodes.List, mainRectangle.X, mainRectangle.Y);

            }

            else if (Paint != null)
            {
                Paint(this, e);
            }

        }

        public void OnGotFocus(EventArgs e)
        {
            hasFocus = true;
            if (GotFocus != null)
            {
                GotFocus(this, e);
            }
            owner.Invalidate();
        }

        public void OnLostFocus(EventArgs e)
        {
            hasFocus = false;
            if (LostFocus != null)
            {
                LostFocus(this, e);
            }
            owner.Invalidate();
        }

        public void OnMouseClick(MouseEventArgs e)
        {
            mouseX = e.X;
            mouseY = e.Y;
            Invalidate();
            
            if (Click != null)
            {
                Click(this, e);
            }
        }

        public void OnKeyPress(KeyPressEventArgs e)
        {
            if (KeyPress != null)
            {
                KeyPress(this, e);
            }
        }

        public void OnKeyDown(KeyEventArgs e)
        {
            if (KeyDown != null)
            {
                KeyDown(this, e);
            }
        }

        #endregion

        #region ITreeView Members

        public ITreeNodeCollection Nodes
        {
            get { return nodes; }
        }

        public bool Scrollable
        {
            get { return scroll; }
            set{ scroll = value; Invalidate(); }
        }

        public ITreeNode SelectedNode
        {
            get { return selected; }
            set { selected = value; }
        }

        #endregion


    }


}
